package com.k7.mobile.platform.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.NoRouteToHostException;
import java.net.SocketException;
import java.net.UnknownHostException;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.log4j.Logger;


public class HttpClientUtil {
	private static Logger log = Logger.getLogger(HttpClientUtil.class);
	private static int DEFAULT_CONN_TIMEOUT = 3000;
	private static int DEFAULT_READ_TIMEOUT = 3000;
	
	private static String getHttpResponse(String url,NameValuePair[] params,boolean isPost,String charset) {
		return getHttpResponse(url, params, isPost, charset, DEFAULT_CONN_TIMEOUT, DEFAULT_READ_TIMEOUT);
	}
	
	
	private static String getHttpResponse(String url,
								 NameValuePair[] params,
								 boolean isPost,
								 String charset, 
								 int connectionTimeOut, 
								 int readTimeOut) {
		String result = "";

		HttpClient client = new HttpClient();
		HttpClientParams httpParams = new HttpClientParams();
		httpParams.setUriCharset(charset);
		httpParams.setContentCharset(charset);
		httpParams.setHttpElementCharset(charset);
		httpParams.setCredentialCharset(charset);
		
		if(connectionTimeOut <= 0){
			client.getHttpConnectionManager().getParams().setConnectionTimeout(DEFAULT_CONN_TIMEOUT);
		}else{
			client.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeOut);
		}
		
		if(readTimeOut <= 0){
			client.getHttpConnectionManager().getParams().setSoTimeout(DEFAULT_READ_TIMEOUT);
		}else{
			client.getHttpConnectionManager().getParams().setSoTimeout(readTimeOut);
		}
        
        
		client.setParams(httpParams);
		HttpMethod method;
				
		if (isPost){
			method = new PostMethod(url);
		}else{
			method = new GetMethod(url);
		}		
		
		try {
			method.addRequestHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1)");			
			method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, charset);			
			method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,	new DefaultHttpMethodRetryHandler(3, false));

			if (isPost) {
				if(params != null){
					((PostMethod) method).setRequestBody(params);
				}
			}else {
				if (params != null){
					method.setQueryString(params);
				}
			}

			int statusCode = client.executeMethod(method);
			log.debug(method.getStatusLine());
			if ((statusCode == HttpStatus.SC_MOVED_TEMPORARILY)
					|| (statusCode == HttpStatus.SC_MOVED_PERMANENTLY)
					|| (statusCode == HttpStatus.SC_SEE_OTHER)
					|| (statusCode == HttpStatus.SC_TEMPORARY_REDIRECT)) {

				Header locationHeader = method.getResponseHeader("Location");
				String location = null;
				if (locationHeader != null) {
					location = locationHeader.getValue();
					log.debug("-----------The page was redirected to:" + location);
					method.releaseConnection();
					return getHttpResponse(location, params,true,charset);
				} else {
					log.debug("-----------Location field value is null.");
				}
			} else if (statusCode != HttpStatus.SC_OK) {
				log.debug("Method failed: " + method.getStatusLine());
			}
			
			InputStream is = method.getResponseBodyAsStream();
			ByteArrayOutputStream bos = new ByteArrayOutputStream();

			int c;
			while ((c = is.read()) != -1) {
				bos.write(c);
			}

			bos.flush();
			result = bos.toString(charset);
			log.debug("result:" + result);	
			
			bos.close();
			is.close();
		} catch (HttpException e) {
			log.error("-----------Fatal protocol violation: " + e.getMessage());
			return null;
		} catch (NoRouteToHostException e) {
			log.error("-----------Fatal no route to host error: " + e.getMessage());
			return null;
		} catch (UnknownHostException e) {
			log.error("-----------Fatal unknown  host error: " + e.getMessage());
			return null;
		} catch (SocketException e) {
			log.error("-----------Fatal unknown  host error: " + e.getMessage());
			return null;
		} catch (IOException e) {
			log.error("-----------Fatal transport error: " + e.getMessage());
			return null;
		} catch (Exception e) {
			log.error("-----------Fatal error: " + e.getMessage());
			return null;
		} 
		
		return result;
	}
	
	
	public static String post(String url, NameValuePair[] params, String charset, int connectionTimeOut, int readTimeOut){
		if (charset == null) {
			charset = System.getProperty("file.encoding");
			
		}
		
		try{					
			for (int i=0;i<params.length;i++){
				if (params[i].getValue()!=null)
					params[i].setValue(new String(params[i].getValue().getBytes(), charset));
			}
			
			return getHttpResponse(url, params, true, charset, connectionTimeOut, readTimeOut);
		}catch(Exception e){
			log.error("-----------post error: " + e.getMessage());
			return null;
		}		
	}
	
	public static String get(String url, String charset, int connectionTimeOut, int readTimeOut) {
		if (charset == null) {
			charset = System.getProperty("file.encoding");
		}
		try{
			return getHttpResponse(url, null, false, charset, connectionTimeOut, readTimeOut);
		}catch(Exception e){
			log.error("-----------get error: " + e.getMessage());
			return null;
		}	
	}	
	public static void main(String[] args){
		try{
		String str=HttpClientUtil.get("http://imdev3.corp.cnb.yahoo.com/tws.php?keyword=����", "UTF-8", 0, 0);
		log.info(str);
		}catch(Exception e){
			log.error(e);
		}
	}
	
}
